package com.yzf.demo.demo.ReflectionMechanism;

import lombok.Data;
import lombok.Getter;

/**
 * Created by 于占峰 on 2020/3/24/024.
 * 反射机制
 * 指在JAVA程序运行状态中
 * 给定一个类(class)对象,通过反射获得这个类对象的所有成员结构;
 * 给定的一个具体的对象,能够动态地调用它的方法及对任意属性值进行获取和赋值;
 * 这种动态获取类的内容、创建对象、以及动态调用对象的方法及操作属性的机制.
 */
@Data
public class DemoBean {
    public String name;
    public Integer age;
    @Getter
    private String sex;

    public DemoBean() {
    }

    private DemoBean(String name) {
    }

    public DemoBean(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    private DemoBean(Integer age) {
        this.age = age;
    }

    public void demoMethod() {
        System.out.println("类的方法");
    }

    public static void main(String[] args) {
        try {
            //获得类的实例的四种方法
            //1.调用运行时类本身的.class属性
            Class clazz = DemoBean.class;
            DemoBean demoBean = (DemoBean) clazz.newInstance();
            System.out.println(demoBean);
            //2.通过类名获得实例
            Class clazz1 = Class.forName("com.yzf.demo.demo.ReflectionMechanism.DemoBean");
            DemoBean demoBean1 = (DemoBean) clazz1.newInstance();
            System.out.println(demoBean1);
            //3.通过运行时类的对象获取
            DemoBean demoBean2 = new DemoBean();
            Class clazz2 = demoBean2.getClass();
            DemoBean demoBean3 = (DemoBean) clazz2.newInstance();
            System.out.println(demoBean3);
            //4.通过类加载器
            ClassLoader clssLoader = clazz.getClassLoader();
            Class clazz3 = clssLoader.loadClass("com.yzf.demo.demo.ReflectionMechanism.DemoBean");
            DemoBean demoBean4 = (DemoBean) clazz3.newInstance();
            System.out.println(demoBean4);
            //一些基本操作方法
            System.out.println(clazz.getModifiers());//获得类的修饰符
            System.out.println(clazz.getSuperclass());//获得父类
            System.out.println(clazz.getClassLoader());//获得类的加载器
            System.out.println(clazz.getPackage());//获得类的包名
            System.out.println(clazz.getName());//获得全路径类名
            System.out.println(clazz.getSimpleName());//获得类的简单名称
            System.out.println(clazz.getDeclaredField("name"));//获得类的指定字段
            System.out.println(clazz.getDeclaredFields());//获得类的所有字段列表
            System.out.println(clazz.getMethod("demoMethod"));//根据方法名获得类的方法
            System.out.println(clazz.getMethods());//获得类的方法列表
            System.out.println(clazz.getInterfaces());//获得类实现的接口列表
            System.out.println(clazz.getDeclaredConstructor());//获得类的构造器
            System.out.println(clazz.getAnnotation(Data.class));//获得类的注解
            System.out.println(clazz.getAnnotations());//获得类的注解列表
            System.out.println(clazz.getAnnotatedSuperclass());//返回父类的注解的AnnotatedType
            System.out.println(clazz.getAnnotatedInterfaces());//返回注释的AnnotatedType
            //返回表示某些接口的 Type，这些接口由此对象所表示的类或接口直接实现
            System.out.println(clazz.getGenericInterfaces());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
